import type { useDefaultForm } from "@/hooks";
import type { ShallowRef } from "vue";

type CurdRequests = {
  listRequest: ReturnType<typeof useListRequest<"/api/user", "GET">>;
  addRequest: ReturnType<typeof useRequest<"/api/user", "POST">>;
  detailRequest: ReturnType<typeof useRequest<"/api/user/:id", "GET">>;
  editRequest: ReturnType<typeof useRequest<"/api/user/:id", "PUT">>;
  removeRequest: ReturnType<typeof useRequest<"/api/user/:id", "DELETE">>;
};

export abstract class BaseService {
  static instances: Map<string, any> = new Map();

  static getInstance<T>(this: { new (): T }): T {
    const className = this.name;
    if (!BaseService.instances.has(className)) {
      BaseService.instances.set(className, new this());
    }
    return BaseService.instances.get(className) as T;
  }

  abstract columns(): GTableFieldType[];

  // abstract search(): Promise<void>
  abstract searchForm(
    where: ShallowRef<Record<string, any>>
  ): ReturnType<typeof useDefaultForm>;
  abstract searchWhere(): ShallowRef<Record<string, any>>;
  searchProps?: ReturnType<typeof useDefaultForm>["props"];
  async search() {
    if (!this.searchProps) {
      const where = this.searchWhere();
      const { props } = this.searchForm(where);
      this.searchProps = props;
    }
  }

  abstract add(): Promise<void>;
  abstract detail(row: unknown): Promise<void>;
  abstract edit(row: unknown): Promise<void>;
  abstract remove(rows: unknown[]): Promise<void>;
}
